<?php
	require_once('/validate/validate.php');
	require_once('/database/DBConfig.php');
	require_once('/hash/hashConfig.php');
	require_once('/hash/PasswordHash.php');

	class RegisterHandler {
		const EVERYTHING_WENT_BETTER_THEN_EXPECTED = 0;
		const USERNAME_TAKEN = 1;
		const PASSWORD_NO_MATCH = 2;
		const WRONG_EMAIL = 3;
		const WRONG_PERSONNUMBER = 4;
		const PASSWORD_INVALID = 5;
		
		private $m_db = null;
		
		public function __construct(Database $db) {
			$this->m_db = $db;
		}
		
		/**
		 * Register user
		 * @param RegisterView $rw
		 * @return string $errorCode
		 */
		public function Register(RegisterView $rw) {
			$v = new Validate();
			$pw = $rw->GetPassword();
			$pwa = $rw->GetSecondPassword();
			$email;
			$pn;
			
			if (isset($pw)) {
				if ($pw === $pwa) {
					if ($v->ValidatePassword($pw)) {
						$email = $rw->GetEmail();
						if (isset($email)) {
							if ($v->ValidateEmail($email)) {
								$pn = $rw->GetPersonNumber();
								if (isset($pn)) {
									if ($v->ValidatePersonNumber($pn)) {
										return $this->RegisterUser($rw, $v);
									}
									return self::WRONG_PERSONNUMBER;
								}
							}
							return self::WRONG_EMAIL;
						}
					}
					return self::PASSWORD_INVALID;
				}
				return self::PASSWORD_NO_MATCH;
			}
		}
		
		/**
		 * Inserts registerd user in database
		 * @param RegisterView $rw
		 * @param Validate $v
		 * @return const
		 */
		private function RegisterUser(RegisterView $rw, Validate $v) {
			$user = $rw->GetUserName();
			$pw;
			$pn;
			$email;
			$hash = null;
			
			$tempUser = $this->SelectUsername();
			
			if ($tempUser == $user) {
				return self::USERNAME_TAKEN;
			} else {
				$pw = $rw->GetPassword();
				$hash = $this->PasswordHash($pw);
				$pn = $rw->GetPersonNumber();
				$pn = $v->ValidatePersonNumber($pn);
				$email = $rw->GetEmail();
				
				$this->InsertUser($user, $hash, $pn, $email);
				
				return self::EVERYTHING_WENT_BETTER_THEN_EXPECTED;
			}
		}

		/**
		 * @param string $pw
		 * @return string $hash
		 */
		public function PasswordHash($pw) {
			$hasher = null;
			$hashConfig = null;
			$hash = null;
			$i = 0;
			
			do {
				$hashConfig = new hashConfig();
				$hasher = new PasswordHash($hashConfig);
				$hash = $hasher->HashPassword($pw);
				$i++;
			} while (strlen($hash) < 20 || $i > 10);
			
			return $hash;
		}

		/**
		 * Runs query to select username
		 * @param Database $db
		 * @param DBConfig $dbc
		 * @return String Username
		 */
		public function SelectUsername() {
			$sql = "SELECT Username FROM userid WHERE Username = ?";
			$stmt = $this->m_db->Prepare($sql);
			$stmt->bind_param("s", $user);
			return $this->m_db->SelectOne($stmt);
		}
		
		/**
		 * Runs insert query to save user
		 * @param string $user
		 * @param string $hash
		 * @param string $pn
		 * @param string $email
		 */
		public function InsertUser($user, $hash, $pn, $email) {
			$sql = "INSERT INTO userid (Username, Password, Personnumber, Email) VALUES (?, ?, ?, ?)";
			$stmt = $this->m_db->Prepare($sql);
			
			$stmt->bind_param("ssss", $user, $hash, $pn, $email);
	
			$insertId = $this->m_db->RunInsertQuery($stmt);
		}

		/**
		 * @param RegisterView $rw
		 * @return string Testdata
		 */
		public function Test(RegisterView $rw) {
			
			if (!$this->RegisterUser("ratt", "rattratt")) {
				echo "Kan inte registrera en användare.";
				return false;
			}
			
			return true;
		}
	}
?>